package com.kuang.thread.Producer_Consumer;

//测试生产者消费者模型，管理法
//需要生产者，消费者，产品，缓冲区
public class TestPC01 {
    public static void main(String[] args) throws InterruptedException {
        SynContainer synContainer = new SynContainer();
        new Producer(synContainer).start();
        //通过更改这里的值来控制过量生产使其爆满或者使其不够（生产一个消费一个）
        Thread.sleep(100);
        new Consumer(synContainer).start();
    }
}

//生产者
class Producer extends Thread{
    SynContainer synContainer;
    public Producer(SynContainer synContainer){
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("生产了第" + i + "个产品");
            synContainer.push(new Product(i));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

///消费者
class Consumer extends Thread{
    SynContainer synContainer;
    public Consumer(SynContainer synContainer){
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        super.run();
        for (int i = 0; i < 100 ; i++) {
            Product consumedProduct = synContainer.pop();
            System.out.println("消费了第" + consumedProduct.id + "个产品");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//产品
class Product{
    int id;

    public Product(int id) {
        this.id = id;
    }
}

//缓冲区
class SynContainer{
    //需要一个容器大小
    Product[] products = new Product[10];
    // 容器计数器
    int count = 0;

    //生产者放入产品
    public synchronized void push(Product product){
        //如果容器满了，需要等待消费者消费
        if (count == products.length){
            //通知消费者等待，生产等待
            System.out.println("产品已经满了");
            try {
                //进行等待
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            //如果没有满，需要放入产品
            products[count] = product;
            count++;
            //可以通知消费者消费了
            this.notifyAll();
        }
    }
    //消费者消费产品

    public synchronized Product pop(){
        //判断能否消费
        if(count==0){
            //等待生产者生产，消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }else {
            //可以消费
            //吃完了
            count--;
            Product product = products[count];
            this.notifyAll();
            return product;
        }
    }
}


